package com.university.evaluation.service;

import com.alibaba.fastjson2.JSON;
import com.university.evaluation.entity.EvaluationRule;
import com.university.evaluation.mapper.EvaluationRuleMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * 考评规则配置服务
 * 核心校验：指标权重总和必须为100%，支持学院自定义指标
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EvaluationRuleService {

    private final EvaluationRuleMapper ruleMapper;

    /**
     * 添加学院考评规则
     * @param collegeId 学院ID
     * @param indicators 考评指标列表（含名称和权重）
     * @param semester 生效学期
     * @return 规则ID
     */
    @Transactional
    public String addCollegeRule(String collegeId, List<Indicator> indicators, String semester) {
        log.info("添加学院考评规则：collegeId={}, semester={}, indicators={}", collegeId, semester, indicators);
        
        // 1. 校验指标权重总和（必须等于100）
        BigDecimal totalWeight = indicators.stream()
                .map(Indicator::getWeight)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (totalWeight.compareTo(new BigDecimal(100)) != 0) {
            throw new BusinessException("指标权重总和必须为100%，当前总和：" + totalWeight);
        }

        // 2. 校验指标名称唯一性（同一规则下指标名称不可重复）
        long distinctCount = indicators.stream()
                .map(Indicator::getName)
                .distinct()
                .count();
        if (distinctCount != indicators.size()) {
            throw new BusinessException("存在重复的指标名称");
        }

        // 3. 校验学院是否已有同学期的规则
        EvaluationRule existingRule = ruleMapper.findByCollegeAndSemester(collegeId, semester);
        if (existingRule != null) {
            throw new BusinessException("该学院在此学期已存在考评规则，请先删除或修改现有规则");
        }

        // 4. 保存规则（指标以JSON格式存储）
        EvaluationRule rule = new EvaluationRule();
        rule.setRuleId(UUID.randomUUID().toString());
        rule.setCollegeId(collegeId);
        rule.setIndicators(JSON.toJSONString(indicators)); // 转为JSON字符串存储
        rule.setSemester(semester);
        rule.setStatus(EvaluationRule.STATUS_ENABLED);
        rule.setCreateTime(LocalDateTime.now());
        rule.setUpdateTime(LocalDateTime.now());
        ruleMapper.insert(rule);

        log.info("学院考评规则添加成功：ruleId={}", rule.getRuleId());
        return rule.getRuleId();
    }

    /**
     * 调整考评维度权重
     * @param ruleId 规则ID
     * @param indicators 新的指标列表
     * @return 调整结果
     */
    @Transactional
    public RuleAdjustResult adjustRule(String ruleId, List<Indicator> indicators) {
        log.info("调整考评规则权重：ruleId={}, indicators={}", ruleId, indicators);
        
        // 1. 查询规则是否存在
        EvaluationRule rule = ruleMapper.selectById(ruleId);
        if (rule == null) {
            return new RuleAdjustResult(false, "规则不存在");
        }

        // 2. 校验指标权重总和
        BigDecimal totalWeight = indicators.stream()
                .map(Indicator::getWeight)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (totalWeight.compareTo(new BigDecimal(100)) != 0) {
            return new RuleAdjustResult(false, "指标权重总和必须为100%，当前总和：" + totalWeight);
        }

        // 3. 校验指标名称唯一性
        long distinctCount = indicators.stream()
                .map(Indicator::getName)
                .distinct()
                .count();
        if (distinctCount != indicators.size()) {
            return new RuleAdjustResult(false, "存在重复的指标名称");
        }

        // 4. 更新规则
        EvaluationRule updateRule = new EvaluationRule();
        updateRule.setRuleId(ruleId);
        updateRule.setIndicators(JSON.toJSONString(indicators));
        updateRule.setUpdateTime(LocalDateTime.now());
        ruleMapper.updateById(updateRule);

        log.info("考评规则权重调整成功：ruleId={}", ruleId);
        return new RuleAdjustResult(true, "权重调整成功");
    }

    /**
     * 获取学院当前生效的考评规则
     * @param collegeId 学院ID
     * @param semester 学期
     * @return 考评规则
     */
    public EvaluationRule getCurrentRule(String collegeId, String semester) {
        return ruleMapper.findByCollegeAndSemesterAndStatus(collegeId, semester, EvaluationRule.STATUS_ENABLED);
    }

    /**
     * 考评指标类
     */
    public static class Indicator {
        private String name;        // 指标名称
        private BigDecimal weight;  // 权重

        public Indicator() {}

        public Indicator(String name, BigDecimal weight) {
            this.name = name;
            this.weight = weight;
        }

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public BigDecimal getWeight() { return weight; }
        public void setWeight(BigDecimal weight) { this.weight = weight; }

        @Override
        public String toString() {
            return "Indicator{name='" + name + "', weight=" + weight + "}";
        }
    }

    /**
     * 规则调整结果类
     */
    public static class RuleAdjustResult {
        private boolean success;
        private String message;

        public RuleAdjustResult(boolean success, String message) {
            this.success = success;
            this.message = message;
        }

        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
    }

    /**
     * 业务异常类
     */
    public static class BusinessException extends RuntimeException {
        public BusinessException(String message) {
            super(message);
        }
    }
}
